﻿@page "/"
@inject CacheService cacheService
@inject MessageService messageService
@inject DialogService dialogService
@using System.Threading
@using System.Threading.Tasks
@using JT808Gateway.Core
@using JT808Protocol.Models
@using JT808Protocol.Models.BodyParserStrategy
@using JT808Protocol.Models.Enums
@using Microsoft.Extensions.Caching.Memory

<div>
<div class="row">
   <span style="font-size:large">当前在线数:@SessionCount</span>
</div>
<div class="row" style="margin-top:10px">
    <div class="col-4 col-sm-4">
        <label style="display:inline">选择设备:</label>
        <Select TValue="string" Items="Devices" ShowSearch="true" AutoClearSearchText="true" OnSelectedItemChanged="@((e)=>{
                SelectedDevice = e;
                return Task.CompletedTask;
             })">
        </Select>
    </div>
</div>
<div style="margin-top:20px">
    <label>
    1.终端参数设置:
    </label>
    <Select style="margin-top:10px" TValue="string" Items="ParamTypes" OnSelectedItemChanged="@((e)=>{
               SelectedParamType = e;
               return Task.CompletedTask;
            })">
    </Select>
    <Textarea style="margin-top:10px" @bind-Value="@DeviceParam" placeholder="请输入参数值"></Textarea>
    <Button style="margin-top:10px" Text="发送" OnClick="@(e=>{
        if(string.IsNullOrEmpty(DeviceParam)){
            messageService.Show(new MessageOption{
                   Content = "终端参数值不能为空",Color= Color.Danger,ShowDismiss = true
             });
            return;
         }
             
        EnumDeviceParamType paramType = (EnumDeviceParamType)Convert.ToInt32(SelectedParamType.Value);
        Send((sim,serialNum,version)=> JT808PackageBuilder.DeviceControl.SetParam(paramType,DeviceParam,sim,serialNum,version));
        })">
    </Button>
</div>
<div style="margin-top:15px">
    <label>
    2.文本下发:
    </label>
    <Textarea style="margin-top:10px" @bind-Value="@TextContent" placeholder="请输入下发文本"></Textarea>
    <div style="margin-top:10px">
       <Dropdown style="display:inline" TValue="int" Items="TextSendFlags" OnSelectedItemChanged="@((e)=>{
               SelectedSendFlag = e;
               return Task.CompletedTask;
        })">
       </Dropdown>
       <Button style="display:inline" Text="发送" OnClick="@(e=>{
             if(string.IsNullOrEmpty(TextContent)){
                 messageService.Show(new MessageOption{
                        Content = "下发文本不能为空",Color= Color.Danger,ShowDismiss = true
                });
                return;
             }
            
        EnumTextSendFlag flag = (EnumTextSendFlag)Convert.ToInt32(SelectedSendFlag.Value);
        Send((sim,serialNum,version)=> JT808PackageBuilder.DeviceControl.SendText(flag,TextContent,sim,serialNum,version));
        })">
     </Button>
   </div>
</div>
<div style="margin-top:15px">
    <label>
    3.终端查询:
    </label>
    <Button Text="位置信息查询" OnClick="e=> 
        Send((sim,serialNum,version)=> JT808PackageBuilder.DeviceQuery.QueryLocation(sim,serialNum,version))">
    </Button>
    <Button Text="查询终端参数" OnClick="e=> 
        Send((sim,serialNum,version)=> JT808PackageBuilder.DeviceQuery.QueryParams(sim,serialNum,version))">
    </Button>
</div>
<div style="margin-top:15px">
    <label>
    4.终端控制①:
    </label>
    <Button Text="终端关机" OnClick="e=> Send((sim,serialNum,version)=> JT808PackageBuilder.DeviceControl.Shutdown(sim,serialNum,version))"></Button>
    <Button Text="终端复位" OnClick="e=> Send((sim,serialNum,version)=> JT808PackageBuilder.DeviceControl.Reset(sim,serialNum,version))"></Button>
    <Button Text="终端恢复出厂设置" OnClick="e=> Send((sim,serialNum,version)=> JT808PackageBuilder.DeviceControl.ResetToFactorySetting(sim,serialNum,version))"></Button>
    <Button Text="关闭数据通信" OnClick="e=> Send((sim,serialNum,version)=> JT808PackageBuilder.DeviceControl.TurnOffCommunication(sim,serialNum,version))"></Button>
    <Button Text="关闭所有无线通信" OnClick="e=> Send((sim,serialNum,version)=> JT808PackageBuilder.DeviceControl.TurnOffAllWirelessCommunication(sim,serialNum,version))"></Button>
</div>
<div style="margin-top:15px;margin-bottom:50px">
    <label>
    4.终端控制②:
    </label>
    <Textarea style="margin-top:10px" @bind-Value="@CmdParam1" placeholder="格式: URL 地址;拨号点名称;拨号用户名;拨号密码;地址;TCP 端口;UDP 端口;制造商 ID; 硬件版本;固件版本; 连接到指定服务器时限 (若某个参数无值，则放空)"></Textarea>
    <Button style="margin-top:10px" Text="无线升级" OnClick="@(e=>{ 
            if(string.IsNullOrEmpty(CmdParam1)){
                messageService.Show(new MessageOption{
                    Content = "命令参数不能为空",Color= Color.Danger,ShowDismiss = true
                });
                return;
            }
            Send((sim,serialNum,version)=> JT808PackageBuilder.DeviceControl.WirelessUpgrade(CmdParam1,sim,serialNum,version));
        })">
    </Button>
    <Textarea style="margin-top:10px" @bind-Value="@CmdParam2" placeholder="格式: 连接控制;监管平台鉴权码;拨号点名称;拨号用户名;拨号密码;地址;TCP 端口;UDP 端口;连接到指定服务器时限 (若某个参数无值，则放空，若连接控制值为 1，则无后继参数)"></Textarea>
    <Button style="margin-top:10px" Text="控制终端连接指定服务器" OnClick="@(e=>{
            if(string.IsNullOrEmpty(CmdParam2)){
                messageService.Show(new MessageOption{
                    Content = "命令参数不能为空",Color= Color.Danger,ShowDismiss = true
                });
                return;
            }
            Send((sim,serialNum,version)=> JT808PackageBuilder.DeviceControl.ConnectServer(CmdParam2,sim,serialNum,version));
        })">
    </Button>
</div> 
</div>

@code{
    private int SessionCount { 
        get
        {
            return SessionManager.Instance.SessionList.Count;
        } 
    }

    private List<SelectedItem> Devices { get; set; }

    private SelectedItem SelectedDevice { get; set; }

    private List<SelectedItem> TextSendFlags { get; set; }

    private SelectedItem SelectedSendFlag { get; set; }

    private List<SelectedItem> ParamTypes { get; set; }

    private SelectedItem SelectedParamType { get; set; }

    private string DeviceParam { get; set; }

    private string TextContent { get; set; }

    private string CmdParam1 { get; set; } 

    private string CmdParam2 { get; set; }

    protected override Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            Devices = new List<SelectedItem>();

            ParamTypes = new List<SelectedItem>();

            TextSendFlags = new List<SelectedItem>();

            foreach (var @enum in EnumTextSendFlagHelper.GetEnum())
            { 
                TextSendFlags.Add(new SelectedItem
                {
                    Text = @enum.key,
                    Value = @enum.value.ToString(),
                });
            }

            SelectedSendFlag = TextSendFlags.First();

            foreach(var @enum in EnumDeviceParamTypeHelper.GetEnum())
            {
                //获取描述对象
                var desc = EnumDeviceParamTypeHelper.GetDescription((EnumDeviceParamType)@enum.value);
                var dispalyText = $"0x{@enum.value.ToString("X4")} {@enum.key} {(desc!=null && desc.UnitDesc!=string.Empty? $"{desc.UnitDesc}":null)}";

                ParamTypes.Add(new SelectedItem
                {
                    Text = dispalyText,
                    Value = @enum.value.ToString("X4")
                });
            }

            Task.Run(() =>
            {
                while (true)
                {
                    RefreshDevices();

                    InvokeAsync(() =>
                    {
                    //定时刷新
                    StateHasChanged();
                    });

                    Thread.Sleep(5 * 1000);
                }
            });
        }
        return base.OnAfterRenderAsync(firstRender);
    }

    private void RefreshDevices()
    {
        Devices.Clear();

        foreach (var session in SessionManager.Instance.SessionList)
        {
            var p= (JT808Protocol.Models.JT808Package)session.DataContext;
            if (p == null) continue;

            var item = new SelectedItem
            {
                Text = p.Header.SimNumber,
                Value = p.Header.SimNumber
            };

            Devices.Add(item);
        }

        if (Devices.Count == 1)
            SelectedDevice = Devices.First();
        else if (Devices.Count == 0)
            SelectedDevice = null;
    }

    /// <summary>
    /// 获取最新流水号
    /// </summary>
    private bool GetSerialNumber(string simNumber,out ushort? serialNumber) {
        var reportTime = cacheService.GetReportTime(simNumber);
        if (reportTime!=null &&  (DateTime)reportTime < DateTime.Now.AddMinutes(-5))
        {
            messageService.Show(new MessageOption
            {
                Content = "设备掉线中",
                Color = Color.Danger,
                ShowDismiss=true
            });
            serialNumber = null;
            return false;
        }
        serialNumber = cacheService.GetSerialNum(simNumber);
        return true;
    }

    /// <summary>
    /// 获取版本
    /// </summary>
    private bool GetProtocolVersion(string simNumber,out JT808ProtocolVersion? verison) {
        verison = cacheService.GetVersion(simNumber);
        return true;
    }

    /// <summary>
    /// 获取选中设备
    /// </summary>
    /// <param name="simNumber"></param>
    /// <returns></returns>
    private bool GetSelectedDevice(out string simNumber){
        bool ret = false;
        simNumber = "";
        if (SelectedDevice != null)
        {
            ret = true;
            simNumber = SelectedDevice.Text;
        }
        else
        {
            messageService.Show(new MessageOption
            {
                Content = "当前没有选中设备",
                Color = Color.Danger,
                ShowDismiss=true
            });
        }
        return ret;
    }

    /// <summary>
    /// 发送数据
    /// </summary>
    /// <param name="func"></param>
    private async void Send(Func<string,ushort,JT808ProtocolVersion,JT808Package> func)
    {
        if(GetSelectedDevice(out string sim))
        {
            if(GetSerialNumber(sim,out ushort? serialNum) && GetProtocolVersion(sim,out JT808ProtocolVersion? version))
            {
                try
                {
                    var package = func(sim, serialNum.Value, version.Value);
                    await SessionManager.Instance.Send(sim,package.WriteBuffer(isEsc:true));

                    await messageService.Show(new MessageOption { Color = Color.Success, Content = "发送成功", ShowDismiss = true });
                }
                catch (Exception ex)
                {
                    await messageService.Show(new MessageOption { Color = Color.Danger, Content = $"发送失败:{ex.Message},StackTrace:{ex.StackTrace}", ShowDismiss = true });
                }
            }
        }
    }
}
